import serial
from ctypes import CDLL
# import pandas as pd
from utils.ecg_utils import EKG_QRS_detect
import numpy as np
import pickle
import matplotlib.pyplot as plt
import cv2


class HeartSensor(object):
    """
    A Heart Sensor Class.

    sensor = HeartSensor(dev='/dev/ttyUSB0', baud_rate=115200)
    data_list = sensor.read()
    """

    def __init__(self, dev, baud_rate):
        self.ser = serial.Serial(dev, baud_rate)

    def read(self, num=100):
        raw = list(self.ser.read(num))
        idx = 0
        for idx, item in enumerate(raw):
            if item == 170 and raw[idx + 1] == 170:
                break
        start_idx, frame_num = idx, (len(raw) - idx) // 10
        result = [raw[start_idx + i * 10 + 6: start_idx + i * 10 + 10] for i in range(frame_num)]
        result = [(item[0] << 24) | (item[1] << 16) | (item[2] << 8) | item[3] for item in result]
        return result

    def read_continuous(self):
        while True:
            if self.ser.read()[0] == 170:
                if self.ser.read()[0] == 170:
                    d1, d2, d3, d4, d5, d6, d7, d8 = list(self.ser.read(8))
                    result = (d5 << 24) | (d6 << 16) | (d7 << 8) | d8
                    yield result


class TempSensor(object):
    """
    A Temp Sensor Class.

    sensor = TempSensor()
    data = sensor.read()
    """

    def __init__(self):
        self.lib_main = CDLL("/home/pi/libabc.so")

    def read(self):
        return self.lib_main.getTemp()


class Logger(object):
    def __init__(self, heart_max_length=3000, heart_to_draw=1000):
        self.heart_sensor = HeartSensor(dev='/dev/ttyUSB0', baud_rate=115200)
        self.temp_sensor = TempSensor()
        self.heart_max_length, self.heart_to_draw = heart_max_length, heart_to_draw
        self.max_data, self.min_data = 60000, -1000
        self.dist = self.max_data - self.min_data
        self.image_height, self.image_width = 300, 1000
        self.pixel_interval = 3
        self.push_count = 30

    def run(self):
        heart_history, temp_history = [], []
        fig = np.zeros((self.image_height, self.image_width, 3), dtype=np.uint8)
        max_data = 0
        las_pos = 0
        pos1, pos2 = self.image_width-self.pixel_interval, self.image_width-1
        for data in self.heart_sensor.read_continuous():
            pos = int(self.image_height - (data - self.min_data) / self.dist * self.image_height)
            # if pos > self.max_data or pos < self.min_data:
            #     continue
            pos = self.max_data if pos > self.max_data else pos
            pos = self.min_data if pos < self.min_data else pos
            fig = fig[:, self.pixel_interval:, :]
            temp_array = np.zeros((self.image_height, self.pixel_interval, 3), dtype=np.uint8)
            fig = np.column_stack((fig, temp_array))
            cv2.line(fig, (pos1, las_pos), (pos2, pos), (255, 255, 255), 2)
            # cv2.imshow("1", fig)
            # cv2.waitKey(1)
            las_pos = pos
            # self.heart_sensor.ser.reset_input_buffer()


if __name__ == '__main__':
    import matplotlib.pyplot as plt
    import time
    sensor = HeartSensor(dev='/dev/ttyUSB0', baud_rate=115200)
    a = sensor.read(20000)
    print(len(a))
    # with open("test23.p", "wb") as f:
    #     pickle.dump(a, f)
    # logger = Logger(heart_max_length=2000)
    # logger.run()

    # dataframe = pd.DataFrame({"heart": a})
    # dataframe.to_csv("test.csv")
    # print(len(a))
    ecg, fs = np.array(a), 800
    start_time = time.time()
    R_peaks, S_pint, Q_point = EKG_QRS_detect(ecg, fs, QS=True, plot=False)
    print(R_peaks, S_pint, Q_point)
    end_time = time.time()
    print(end_time-start_time)
    # plt.plot(a)
    # plt.savefig("test23.png")
    # plt.show()
    # sensor = TempSensor()
    # data = sensor.read()
    # print(data)
